"""
Generation Session Data Model
Defines the structure for tracking PPT generation sessions.
"""

from pydantic import BaseModel, Field, validator
from typing import List, Optional, Dict, Any
from datetime import datetime
from enum import Enum
from .slide_content import SlideContent
from .ppt_request import PPTRequest


class GenerationStatus(str, Enum):
    """Status of PPT generation process"""
    PENDING = "pending"
    GENERATING = "generating"
    COMPLETED = "completed"
    ERROR = "error"
    CANCELLED = "cancelled"


class GenerationStep(str, Enum):
    """Current step in the generation process"""
    INITIALIZING = "initializing"
    GENERATING_OUTLINE = "generating_outline"
    CREATING_SLIDES = "creating_slides"
    APPLYING_TEMPLATE = "applying_template"
    FINALIZING = "finalizing"
    COMPLETED = "completed"


class GenerationSession(BaseModel):
    """
    Data model for PPT generation sessions
    
    Attributes:
        session_id: Unique identifier for the generation session
        status: Current status of the generation process
        progress: Progress percentage (0-100)
        current_step: Current step in the generation process
        slides: List of generated slide content
        template_config: Configuration for the selected template
        request_data: Original request data
        created_at: Timestamp when session was created
        updated_at: Timestamp when session was last updated
        error_message: Error message if generation failed
        file_path: Path to generated PPT file (when completed)
    """
    
    session_id: str = Field(
        ...,
        min_length=1,
        description="Unique identifier for the generation session"
    )
    
    status: GenerationStatus = Field(
        default=GenerationStatus.PENDING,
        description="Current status of the generation process"
    )
    
    progress: int = Field(
        default=0,
        ge=0,
        le=100,
        description="Progress percentage (0-100)"
    )
    
    current_step: GenerationStep = Field(
        default=GenerationStep.INITIALIZING,
        description="Current step in the generation process"
    )
    
    slides: List[SlideContent] = Field(
        default_factory=list,
        description="List of generated slide content"
    )
    
    template_config: Dict[str, Any] = Field(
        default_factory=dict,
        description="Configuration for the selected template"
    )
    
    request_data: Optional[PPTRequest] = Field(
        None,
        description="Original request data"
    )
    
    created_at: datetime = Field(
        default_factory=datetime.now,
        description="Timestamp when session was created"
    )
    
    updated_at: datetime = Field(
        default_factory=datetime.now,
        description="Timestamp when session was last updated"
    )
    
    error_message: Optional[str] = Field(
        None,
        max_length=1000,
        description="Error message if generation failed"
    )
    
    file_path: Optional[str] = Field(
        None,
        description="Path to generated PPT file (when completed)"
    )
    
    @validator('session_id')
    def validate_session_id(cls, v):
        """Validate session ID is not empty"""
        if not v or not v.strip():
            raise ValueError('Session ID cannot be empty')
        return v.strip()
    
    @validator('progress')
    def validate_progress(cls, v):
        """Ensure progress is within valid range"""
        if v < 0:
            return 0
        elif v > 100:
            return 100
        return v
    
    @validator('updated_at', always=True)
    def set_updated_at(cls, v):
        """Always update the updated_at timestamp"""
        return datetime.now()
    
    @validator('error_message')
    def validate_error_message(cls, v):
        """Clean error message if provided"""
        if v is not None:
            v = v.strip()
            if not v:
                return None
        return v
    
    def update_progress(self, progress: int, step: GenerationStep, status: Optional[GenerationStatus] = None):
        """Update session progress and step"""
        self.progress = max(0, min(100, progress))
        self.current_step = step
        if status:
            self.status = status
        self.updated_at = datetime.now()
    
    def add_slide(self, slide: SlideContent):
        """Add a slide to the session"""
        slide.slide_number = len(self.slides) + 1
        self.slides.append(slide)
        self.updated_at = datetime.now()
    
    def set_error(self, error_message: str):
        """Set session to error state with message"""
        self.status = GenerationStatus.ERROR
        self.error_message = error_message
        self.updated_at = datetime.now()
    
    def complete(self, file_path: str):
        """Mark session as completed with file path"""
        self.status = GenerationStatus.COMPLETED
        self.progress = 100
        self.current_step = GenerationStep.COMPLETED
        self.file_path = file_path
        self.updated_at = datetime.now()
    
    class Config:
        """Pydantic configuration"""
        use_enum_values = True
        json_encoders = {
            datetime: lambda v: v.isoformat(),
            GenerationStatus: lambda v: v.value,
            GenerationStep: lambda v: v.value
        }
        json_schema_extra = {
            "example": {
                "session_id": "session_123456789",
                "status": "generating",
                "progress": 45,
                "current_step": "creating_slides",
                "slides": [],
                "template_config": {
                    "name": "professional",
                    "colors": {"primary": "#2E86AB"}
                },
                "created_at": "2024-01-15T10:30:00",
                "updated_at": "2024-01-15T10:35:00"
            }
        }